ShowTable of Contents
はじめに
XPages の裏側のでは JavaServer Faces の技術が使われています。より良い XPages アプリケーションを作成するには、この JSF の仕組みの理解が必要です。この記事では XPages の裏側で動く JSF のライフサイクルの動きを知るための方法を紹介します。
faces-config.xml の設定
JSF ライフサイクルのフェーズを表示するには、フェーズリスナーとなる Java クラスを実装し、JSF コンテナに登録する必要があります。XPages の場合も、普段は見えないですが NSF ファイルの中に JSF の設定が隠れています。
Domino Designer のメニューから 「ウィンドウ」→「Eclipse ビューの表示」→「パッケージエクスプローラ」を選択して。パッケージエクスプローラーを表示します。これは NSF 内部の設計要素を Eclipse File System を通してひょうじします。
WebContent\WEB-IN フォルダの下の \faces-config.xsml を開き、以下のような <lifecycle> 定義を追加します。
<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
<lifecycle>
<phase-listener>mypackage.MyPhaseListener</phase-listener>
</lifecycle>
</faces-config>
Java クラスの実装
先ほど定義した faces-config.xml にし従い、JSF ライフサイクルを表示するフェーズリスナーを実装します。
Domino Designer で「アプリケーション」タブに戻り「コード/Java」で新規の Java クラスを以下のように定義します。これは先ほどの faces-config.xml に合わせて設定します。
パッケージ: mypackage
クラス: MyPhaseListener
package mypackage;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
public class MyPhaseListener implements PhaseListener {
private static final long serialVersionUID = 1L;
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
public void beforePhase(PhaseEvent phaseEvent) {
System.out.println("=== フェーズ開始 " + phaseEvent.getPhaseId().toString());
}
public void afterPhase(PhaseEvent phaseEvent) {
System.out.println("=== フェーズ終了 " + phaseEvent.getPhaseId().toString());
if (phaseEvent.getPhaseId().equals(PhaseId.RENDER_RESPONSE)) {
System.out.println("=== XPage 処理完了");
System.out.println(".");System.out.println(".");
}
}
}
テスト
これで準備は完了です。
同じ NSF ファイルに適当な XPage を作成します。この XPage にはページの更新を行うボタンも配置してください。以下のサンプルでは XPage のイベントもあわせて表示するようにイベント処理も追加しています。そして、この XPage をブラウザで表示したり、ボタンを押してページ更新をすることで、JSF ライフサイクルの様子が Domino コンソールに表示されます。
※ Domino Designer でのプレビューのときにはコンソールがないので、出力の内容は log.nsf に表示されます。Domino Designer の notes.ini に DEBUG_CONSOLE=1 を設定して再起動することで Domino のようにコンソールを出力することもできます。
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforePageLoad><![CDATA[#{javascript:print("\tbeforePageLoad event")}]]></xp:this.beforePageLoad>
<xp:this.afterPageLoad><![CDATA[#{javascript:print("\tafterPageLoad event")}]]></xp:this.afterPageLoad>
<xp:this.afterRestoreView><![CDATA[#{javascript:print("\tafterRestoreView event")}]]></xp:this.afterRestoreView>
<xp:this.beforeRenderResponse><![CDATA[#{javascript:print("\tbeforeRenderResponse event")}]]></xp:this.beforeRenderResponse>
<xp:this.afterRenderResponse><![CDATA[#{javascript:print("\tafterRenderResponse event")}]]></xp:this.afterRenderResponse>
Hello XPages !
<xp:br></xp:br>
<xp:button value="Refresh" id="button1">
<xp:eventHandler event="onclick" submit="true"
refreshMode="complete">
</xp:eventHandler>
</xp:button>
</xp:view>
XPage を表示したときのコンソール
作成した XPage をブラウザから最初に表示すると以下のようなコンソールログが表示されます。
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: beforePageLoad event
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: afterPageLoad event
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: === フェーズ開始 RENDER_RESPONSE 6
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: beforeRenderResponse event
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: afterRenderResponse event
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: === フェーズ終了 RENDER_RESPONSE 6
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM: === XPage 処理完了
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM:
[00FC:000B-0EB0] 2013/03/18 23:58:23 HTTP JVM:
ここで Create View/Restore View フェーズの情報が表示されていません。 stackoverflow の Tony のコメント によると、 最初のリクエストに対するパフォーマンスを上げるため Create View/Restore View フェーズの phase listening/notification をバイパスしているとのことです。
部分更新をしたときのコンソール
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ開始 RESTORE_VIEW 1
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: afterRestoreView event
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ終了 RESTORE_VIEW 1
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ開始 APPLY_REQUEST_VALUES 2
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ終了 APPLY_REQUEST_VALUES 2
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ開始 PROCESS_VALIDATIONS 3
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ終了 PROCESS_VALIDATIONS 3
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ開始 UPDATE_MODEL_VALUES 4
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ終了 UPDATE_MODEL_VALUES 4
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ開始 INVOKE_APPLICATION 5
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ終了 INVOKE_APPLICATION 5
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ開始 RENDER_RESPONSE 6
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: beforeRenderResponse evet
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: afterRenderResponse event
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === フェーズ終了 RENDER_RESPONSE 6
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM: === XPage 処理完了
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM:
[00FC:000B-0EB0] 2013/03/18 23:58:33 HTTP JVM:
テスト環境
この記事の内容は Lotus Notes/Domino 8.5.3 FP1 で動作確認しました。